package com.wentao.mall.service.impl;

import com.wentao.mall.commons.OrderStatusEnum;
import com.wentao.mall.exception.MallException;
import com.wentao.mall.exception.MallExceptionEnum;
import com.wentao.mall.filter.CustomerFilter;
import com.wentao.mall.mapper.CartMapper;
import com.wentao.mall.mapper.OrderItemMapper;
import com.wentao.mall.mapper.OrderMapper;
import com.wentao.mall.mapper.ProductMapper;
import com.wentao.mall.model.dto.CreateOrderRequest;
import com.wentao.mall.model.po.*;
import com.wentao.mall.model.vo.CartVo;
import com.wentao.mall.model.vo.OrderItemVo;
import com.wentao.mall.model.vo.OrderVo;
import com.wentao.mall.service.CartService;
import com.wentao.mall.service.OrderService;
import com.wentao.mall.utils.OrderCodeFactory;
import com.wentao.mall.utils.QRCodeGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private CartService cartService;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;

    @Override
    @Transactional(propagation=Propagation.REQUIRES_NEW,isolation= Isolation.READ_COMMITTED,timeout = -1,readOnly = false,noRollbackFor=Exception.class)
    public String createOrder(CreateOrderRequest createOrderRequest, User user) {
        //创建订单，先找出购物车中勾选的项，生成一个订单表项，将勾选的所有购物车项加入订单item表
        //1.获取选中的购物车列表
        List<CartVo> cartList = cartService.cartList(user.getId());
        List<CartVo> tempList = new ArrayList<>();
        for (CartVo cartVo : cartList) {
            if (cartVo.getSelected()==1){
                tempList.add(cartVo);
            }
        }

        //TODO
        cartList=tempList;           //方便jdk垃圾回收

        //2.校验选中列表是否为空
        if (CollectionUtils.isEmpty(cartList)){
            throw new MallException(MallExceptionEnum.CART_IS_EMPTY);
        }
        //3.校验购物车内部数据
        validCartVoList(cartList);
        //4.将购物车的项转为订单项
        List<OrderItem> orderItems = cartToOrderItem(cartList);
        //5.扣库存
        delStock(orderItems);
        //6.清除购物车数据
        clearCartSelected(cartList);
        //7.准备订单号，生成订单
        //计算订单总价
        int orderPrice=0;
        for (CartVo cartVo : cartList) {
            orderPrice+=cartVo.getTotalPrice();
        }
        String orderNo = OrderCodeFactory.getOrderCode(user.getId().longValue());
        Order order = new Order();
        order.setOrderNo(orderNo);
        order.setReceiverAddress(createOrderRequest.getReceiverAddress());
        order.setReceiverMobile(createOrderRequest.getReceiverMobile());
        order.setReceiverName(createOrderRequest.getReceiverName());
        order.setUserId(user.getId());
        order.setTotalPrice(orderPrice);
        order.setUpdateTime(new Date());
        orderMapper.insertSelective(order);
        //8.将订单项保存到数据库
        for(OrderItem orderItem : orderItems){
            orderItem.setOrderNo(orderNo);
            orderItemMapper.insertSelective(orderItem);
        }
        return orderNo;
    }

    @Override
    public OrderVo orderDetail(String orderNo, Integer userId) {
        Order order=orderMapper.selectByOrderNo(orderNo);
        //验证订单是否属于当前用户
        if (order.getUserId()!=userId){
            throw new MallException(MallExceptionEnum.ORDER_NOT_FOUND);
        }
        //找不到该订单，则抛出异常
        if (order==null){
            throw new MallException(MallExceptionEnum.ORDER_NOT_FOUND);
        }
        OrderVo orderVo = new OrderVo();
        BeanUtils.copyProperties(order,orderVo);
        //拿到订单状态名
        orderVo.setOrderStatusName(OrderStatusEnum.codeOf(order.getOrderStatus()).getStatusName());
        //查询并赋值订单项
        OrderItemExample orderItemExample = new OrderItemExample();
        orderItemExample.createCriteria().andOrderNoEqualTo(orderNo);
        List<OrderItem> orderItems = orderItemMapper.selectByExample(orderItemExample);
        List<OrderItemVo> orderItemVoList = new ArrayList<>();
        for (OrderItem orderItem : orderItems) {
            OrderItemVo orderItemVo = new OrderItemVo();
            BeanUtils.copyProperties(orderItem,orderItemVo);
            orderItemVoList.add(orderItemVo);
        }
        orderVo.setOrderItemList(orderItemVoList);
        return orderVo;
    }

    @Override
    public List<OrderVo> orderList(Integer userId) {
        //查询当前用户所有order
        OrderExample orderExample = new OrderExample();
        orderExample.createCriteria().andUserIdEqualTo(userId);
        List<Order> orders = orderMapper.selectByExample(orderExample);
        //此处不用将orders判断是否为空，因为mybatis会自动返回一个空集合
//        if (orders==null){        false
//            return null;
//        }
        System.out.println(orders);
        //将orderList转为orderVoList
        List<OrderVo> orderVoList = new ArrayList<>();
        for (Order order : orders) {
            OrderVo orderVo = new OrderVo();
            BeanUtils.copyProperties(order,orderVo);
            //拿到订单状态名
            orderVo.setOrderStatusName(OrderStatusEnum.codeOf(order.getOrderStatus()).getStatusName());
            //查询并赋值订单项
            OrderItemExample orderItemExample = new OrderItemExample();
            orderItemExample.createCriteria().andOrderNoEqualTo(order.getOrderNo());
            List<OrderItem> orderItems = orderItemMapper.selectByExample(orderItemExample);
            List<OrderItemVo> orderItemVoList = new ArrayList<>();
            for (OrderItem orderItem : orderItems) {
                OrderItemVo orderItemVo = new OrderItemVo();
                BeanUtils.copyProperties(orderItem,orderItemVo);
                orderItemVoList.add(orderItemVo);
            }
            orderVo.setOrderItemList(orderItemVoList);
             //最后把每个orderVo放入orderVOList
            orderVoList.add(orderVo);
        }
        return orderVoList;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.READ_COMMITTED,timeout = -1,readOnly = false,rollbackFor = Exception.class)
    public void cancelOrder(String orderNo, Integer userId) {
        //判断用户下是否有该订单，若没有则抛出异常
        Order order = orderMapper.selectByOrderNo(orderNo);
        //更改订单状态
        order.setUpdateTime(new Date());
        order.setOrderStatus(OrderStatusEnum.CANCELED.getStatusCode());
        int count = orderMapper.updateByPrimaryKeySelective(order);
        if (count==0){
            throw new MallException(MallExceptionEnum.UPDATE_FAINED);
        }
//        if (order.getUserId()!=userId){
//            throw new MallException(MallExceptionEnum.ORDER_NOT_FOUND);
//        }
//        //删除order表数据
//        int countOrder = orderMapper.deleteByOrderNo(orderNo);
//        if (countOrder==0) {
//            throw new MallException(MallExceptionEnum.DELETE_FAILED);
//        }
//        //删除orderItem表数据
//        int countOderItem = orderItemMapper.deleteByOrderNo(orderNo);
//        if (countOderItem==0) {
//            throw new MallException(MallExceptionEnum.DELETE_FAILED);
//        }
    }

    @Override
    public String orderQrcode(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        String qrPng = createQRCodeByOrder(order);
        pay(orderNo);
        return qrPng;
    }

    private String createQRCodeByOrder(Order order) {
//        try {
//            QRCodeGenerator.generateQRCodeImage("http://支付路径",350,350, Constant.FILE_PATH +"temp.png");
//        } catch (WriterException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
        return "http://127.0.0.1/images/temp.png";
    }

    @Override
    public void pay(String orderNo) {
        //通过订单号查找订单
        Order order = orderMapper.selectByOrderNo(orderNo);
        //校验数据
        if(order==null){
            throw new MallException(MallExceptionEnum.ORDER_NOT_FOUND);
        }
        if(!order.getUserId().equals(CustomerFilter.currentUser.getId())){
            throw new MallException(MallExceptionEnum.ORDER_NOT_FOUND);
        }
        if(order.getOrderStatus().equals(OrderStatusEnum.NOT_PAID.getStatusCode())){
            Order o = new Order();
            o.setId(order.getId());
            o.setOrderNo(orderNo);
            o.setOrderStatus(OrderStatusEnum.PAID.getStatusCode());
            o.setPayTime(new Date());
            orderMapper.updateByPrimaryKeySelective(o);
        } else {
            throw new MallException(MallExceptionEnum.NO_ENUM);
        }
    }

    private void clearCartSelected(List<CartVo> list) {
        for(CartVo cartVo : list){
            cartMapper.deleteByPrimaryKey(cartVo.getId());
        }
    }

    private void delStock(List<OrderItem> orderItemList) {
        for(OrderItem orderItem : orderItemList){
            Product product = productMapper.selectByPrimaryKey(orderItem.getProductId());
            if(product.getStock()<orderItem.getQuantity()){
                throw new MallException(MallExceptionEnum.STOCK_SHORTAGE);
            }
            product.setStock(product.getStock()-orderItem.getQuantity());
            productMapper.updateByPrimaryKeySelective(product);
        }
    }


    private void validCartVoList(List<CartVo> cartVoList){
        for (CartVo cartVo : cartVoList) {
            Product product = productMapper.selectByPrimaryKey(cartVo.getProductId());
            if(product==null||product.getStatus()==0){
                throw new MallException(MallExceptionEnum.PRODUCT_NOT_EXIST);
            }
            if (product.getStock()<cartVo.getQuantity()){
                throw new MallException(MallExceptionEnum.STOCK_SHORTAGE);
            }
        }
    }

    private List<OrderItem> cartToOrderItem(List<CartVo> cartVoList){
        List<OrderItem> result = new ArrayList<>();
        for (CartVo cartVo : cartVoList) {
            OrderItem orderItem = new OrderItem();
            orderItem.setProductId(cartVo.getProductId());
            orderItem.setQuantity(cartVo.getQuantity());
            orderItem.setTotalPrice(cartVo.getTotalPrice());
            orderItem.setProductImg(cartVo.getProductImage());
            orderItem.setProductName(cartVo.getProductName());
            orderItem.setUnitPrice(cartVo.getPrice());
            result.add(orderItem);
        }
        return  result;
    }
}
